
; Variables

inputx      		byte    1
inputy      		byte    1
inputfire   		byte    1

PLAYER_SPEED			= 16
PLAYER_DIAGONAL_SPEED	= 11

PLAYER_STATE_OFF	= 0
PLAYER_STATE_FLYING = 1

PLAYER_STATE		= 0
PLAYER_X 			= 1
PLAYER_Y 			= 3
PLAYER_SPR_MASK 	= 5
PLAYER_SPR_IMASK 	= 6
PLAYER_SPR_INDEX 	= 7
PLAYER_SPR_COLOR 	= 8
PLAYER_SPR_ANM		= 9
PLAYER_SPR_FRAME	= 10
PLAYER_DATA_SIZE 	= 11

player1
	BYTE	1
	WORD	1600, 1600
	BYTE	%00000001, %11111110, 0, COLOR_LIGHTRED, 16, 2
	
player2
	BYTE	1
	WORD	1800, 1800	
	BYTE	%00000010, %11111101, 1, COLOR_LIGHTBLUE, 16, 2

updateplayers
	
	lda #<player1
	sta PGZERO_VECTOR_A
	
	lda #>player1
	sta PGZERO_VECTOR_A+1
	
	jsr readjoystick1
	
	jsr updateplayer
	
	lda #<player2
	sta PGZERO_VECTOR_A
	
	lda #>player2
	sta PGZERO_VECTOR_A+1
	
	jsr readjoystick2
	
	jsr updateplayer

	rts
	
;=======================================================

updateplayer

	ldy #PLAYER_STATE
	lda (PGZERO_VECTOR_A),y
	
	cmp #PLAYER_STATE_FLYING
	bne up_noflying
	
	jsr updateplayerflying
	jmp up_end
	
up_noflying

up_end

	rts
	
;=======================================================

up_aux_speedx	word	0
up_aux_speedy	word	0
up_aux_x		word	0
up_aux_y		word	0

updateplayerflying

	; Startup variables
	lda #0
	sta up_aux_speedx	
	sta up_aux_speedx+1
	sta up_aux_speedy
	sta up_aux_speedy+1
	
	; Check up input
	lda inputy
	cmp #0
	bne up_noup
	
	; Check if we are moving in diagonal
	lda inputx
	cmp #1
	bne up_up_diagonal
	
	; Move up
	lda #-PLAYER_SPEED
	sta up_aux_speedy
	lda #255
	sta up_aux_speedy+1
	
	jmp up_noup

up_up_diagonal

	; Move up
	lda #-PLAYER_DIAGONAL_SPEED
	sta up_aux_speedy
	lda #255
	sta up_aux_speedy+1
	
up_noup
	;=====================

	; Check down input
	lda inputy
	cmp #2
	bne up_nodown
	
	; Check if we are moving in diagonal
	lda inputx
	cmp #1
	bne up_down_diagonal
	
	; Move down
	lda #PLAYER_SPEED
	sta up_aux_speedy
	lda #0
	sta up_aux_speedy+1
	
	jmp up_nodown
	
up_down_diagonal

	; Move down
	lda #PLAYER_DIAGONAL_SPEED
	sta up_aux_speedy
	lda #0
	sta up_aux_speedy+1
		
up_nodown
	;=====================

	; Check left input
	lda inputx
	cmp #0
	bne up_noleft
	
	; Check if we are moving in diagonal
	lda inputy
	cmp #1
	bne up_left_diagonal
	
	; Move left
	lda #-PLAYER_SPEED
	sta up_aux_speedx
	lda #255
	sta up_aux_speedx+1
	
	jmp up_noleft
	
up_left_diagonal

	; Move left
	lda #-PLAYER_DIAGONAL_SPEED
	sta up_aux_speedx
	lda #255
	sta up_aux_speedx+1
	
up_noleft
	;=====================

	; Check right input
	lda inputx
	cmp #2
	bne up_noright
	
	; Check if we are moving in diagonal
	lda inputy
	cmp #1
	bne up_right_diagonal
	
	; Move right
	lda #PLAYER_SPEED
	sta up_aux_speedx
	lda #0
	sta up_aux_speedx+1
	
	jmp up_noright
	
up_right_diagonal

	; Move right
	lda #PLAYER_DIAGONAL_SPEED
	sta up_aux_speedx
	lda #0
	sta up_aux_speedx+1
	
up_noright
	;=====================
			
	; Load x into variable and divide it by 64
	ldy #PLAYER_X
	lda (PGZERO_VECTOR_A),y
	sta up_aux_x
	iny
	lda (PGZERO_VECTOR_A),y
	sta up_aux_x+1
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	lda up_aux_x+1
	lsr
	sta up_aux_x+1
	lda up_aux_x
	ror
	sta up_aux_x
	
	; If speedx < 0, check left limit
	lda up_aux_speedx+1
	and #%10000000
	beq up_speedxpositive
		
	; Limit if x <= 16
	lda up_aux_x
	cmp #12
	bpl up_canadvancex
	
	jmp up_skip_speedx
		
up_speedxpositive
	; speedx > 0, Check right limit
	
	; Limit if x >= 80
	lda up_aux_x
	cmp #80
	bmi up_canadvancex
	
	jmp up_skip_speedx

up_canadvancex
	
	; Add speedx
	
	ldy #PLAYER_X
	lda (PGZERO_VECTOR_A),y
	clc
	adc up_aux_speedx
	sta (PGZERO_VECTOR_A),y
	iny
	lda (PGZERO_VECTOR_A),y
	adc up_aux_speedx+1
	sta (PGZERO_VECTOR_A),y
		
up_skip_speedx

	; Load y into variable and divide it by 64
	ldy #PLAYER_Y
	lda (PGZERO_VECTOR_A),y
	sta up_aux_y
	iny
	lda (PGZERO_VECTOR_A),y
	sta up_aux_y+1
	
	lda up_aux_y+1
	lsr
	sta up_aux_y+1
	lda up_aux_y
	ror
	sta up_aux_y
	
	lda up_aux_y+1
	lsr
	sta up_aux_y+1
	lda up_aux_y
	ror
	sta up_aux_y
	
	lda up_aux_y+1
	lsr
	sta up_aux_y+1
	lda up_aux_y
	ror
	sta up_aux_y
	
	lda up_aux_y+1
	lsr
	sta up_aux_y+1
	lda up_aux_y
	ror
	sta up_aux_y
	
	lda up_aux_y+1
	lsr
	sta up_aux_y+1
	lda up_aux_y
	ror
	sta up_aux_y
	
	; If speedy < 0, check up limit
	lda up_aux_speedy+1
	and #%10000000
	beq up_speedypositive
		
	; Limit if y <= 32
	lda up_aux_y
	cmp #32
	bpl up_canadvancey
	
	jmp up_skip_speedy
		
up_speedypositive
	; speedy > 0, Check down limit
	
	; Limit if y >= 80
	lda up_aux_y
	cmp #90
	bmi up_canadvancey
	
	jmp up_skip_speedy

up_canadvancey

	; Add speedy
	
	ldy #PLAYER_Y
	lda (PGZERO_VECTOR_A),y
	clc
	adc up_aux_speedy
	sta (PGZERO_VECTOR_A),y
	iny
	lda (PGZERO_VECTOR_A),y
	adc up_aux_speedy+1
	sta (PGZERO_VECTOR_A),y
	
up_skip_speedy

	; Update animation
	ldy #PLAYER_SPR_ANM
	
	lda inputy
	cmp #0
	bne up_animnoup
	
	; Pushing up, so decrease anim counter if possible
	lda (PGZERO_VECTOR_A),y
	cmp #0
	beq up_animend
	
	sec
	sbc #1
	sta (PGZERO_VECTOR_A),y
	jmp up_animend
	
up_animnoup
	cmp #2
	bne up_animnodown
	
	; Pushing down, so increase anim counter if possible
	lda (PGZERO_VECTOR_A),y
	cmp #32
	bpl up_animend
	
	clc
	adc #1
	sta (PGZERO_VECTOR_A),y
	jmp up_animend
		
up_animnodown

	; Joystick is centered, so go back to central position
	lda (PGZERO_VECTOR_A),y
	cmp #16
	beq up_animend
	bmi up_animneedssum
	
	; anim needs substract
	sec
	sbc #1
	sta (PGZERO_VECTOR_A),y
	jmp up_animend
	
up_animneedssum

	; anim needs sum
	clc
	adc #1
	sta (PGZERO_VECTOR_A),y
	
up_animend		

	; Calc the sprite frame = anim frame /8
	lda (PGZERO_VECTOR_A),y
	ldy #PLAYER_SPR_FRAME
	lsr
	lsr
	lsr
	sta (PGZERO_VECTOR_A),y
		
	rts
	
;=========================================================

showplayers

	lda #<player1
	sta PGZERO_VECTOR_A
	
	lda #>player1
	sta PGZERO_VECTOR_A+1
	
	jsr showplayer
	
	lda #<player2
	sta PGZERO_VECTOR_A
	
	lda #>player2
	sta PGZERO_VECTOR_A+1
	
	jsr showplayer

	rts
	
;==========================================================

sp_aux_x		word  	0
sp_aux_y		word 	0
sp_aux_idx		byte	0
sp_aux_frame 	byte	0

showplayer

	; Check if player is active
	ldy #PLAYER_STATE
	lda (PGZERO_VECTOR_A),y
	cmp #PLAYER_STATE_OFF
	bne sp_active

	; Player is disable! Don't show
	rts

sp_active	

	; Load the sprite index
	ldy #PLAYER_SPR_INDEX
	lda (PGZERO_VECTOR_A),y
	sta sp_aux_idx

	; Enable the sprite
	lda VIC+21
	ldy	#PLAYER_SPR_MASK
	ora (PGZERO_VECTOR_A),y
	sta VIC+21
	
	; Find the visual coordinates
	ldy #PLAYER_X
	lda (PGZERO_VECTOR_A),y
	sta sp_aux_x
	
	iny
	lda (PGZERO_VECTOR_A),y
	sta sp_aux_x+1
		
	ldy #PLAYER_Y
	lda (PGZERO_VECTOR_A),y
	sta sp_aux_y
	
	iny
	lda (PGZERO_VECTOR_A),y
	sta sp_aux_y+1
	
	; Transform to screen coordinates: Shift 4 bits to the right
	lda sp_aux_x+1
	lsr
	sta sp_aux_x+1
	lda sp_aux_x
	ror
	sta sp_aux_x
	
	lda sp_aux_x+1
	lsr
	sta sp_aux_x+1
	lda sp_aux_x
	ror
	sta sp_aux_x
	
	lda sp_aux_x+1
	lsr
	sta sp_aux_x+1
	lda sp_aux_x
	ror
	sta sp_aux_x
	
	lda sp_aux_x+1
	lsr
	sta sp_aux_x+1
	lda sp_aux_x
	ror
	sta sp_aux_x
	
	; Substract 12 to center sprite
	lda sp_aux_x
	sec
	sbc #12
	sta sp_aux_x
	lda sp_aux_x+1
	sbc #0
	sta sp_aux_x+1
	
	; Y
	lda sp_aux_y+1
	lsr
	sta sp_aux_y+1
	lda sp_aux_y
	ror
	sta sp_aux_y
	
	lda sp_aux_y+1
	lsr
	sta sp_aux_y+1
	lda sp_aux_y
	ror
	sta sp_aux_y
	
	lda sp_aux_y+1
	lsr
	sta sp_aux_y+1
	lda sp_aux_y
	ror
	sta sp_aux_y
	
	lda sp_aux_y+1
	lsr
	sta sp_aux_y+1
	lda sp_aux_y
	ror
	sta sp_aux_y
	
	; Substract 10 to center sprite
	lda sp_aux_y
	sec
	sbc #10
	sta sp_aux_y
	lda sp_aux_y+1
	sbc #0
	sta sp_aux_y+1
				
	; We use Vector B to point to VIC
	lda #<VIC
	sta PGZERO_VECTOR_B
	lda #>VIC
	sta PGZERO_VECTOR_B+1
	
	; Adress of X coordinate of our sprite is:
	; VIC + 2 * SpriteIndex
	lda sp_aux_idx		
	asl
	tay
	
	; Submit the x coordinate
	lda sp_aux_x
	sta (PGZERO_VECTOR_B),y
		
	; Adress of Y coordinate of our sprite is:
	; VIC + 2 * SpriteIndex + 1
	iny
	
	; Submit the y coordinate
	lda sp_aux_y
	sta (PGZERO_VECTOR_B),y
	
	; X MSB check
	lda sp_aux_x+1
	beq sp_nomsb
	
	ldy #PLAYER_SPR_MASK
	lda SPRITESMSB
	ora (PGZERO_VECTOR_A),y
	sta SPRITESMSB
	
	jmp sp_msbend
	
sp_nomsb
	ldy #PLAYER_SPR_IMASK
	lda SPRITESMSB
	and (PGZERO_VECTOR_A),y
	sta SPRITESMSB

sp_msbend
	
	; Calc the id of the sprite
	lda #192
	sta sp_aux_frame
	ldy #PLAYER_SPR_FRAME
	lda (PGZERO_VECTOR_A),y
	clc
	adc sp_aux_frame
	sta sp_aux_frame
	
	; Set the sprite	
	ldy sp_aux_idx
	
	lda #<BUFFER0SPRITESELECTOR
	sta PGZERO_VECTOR_B
	lda #>BUFFER0SPRITESELECTOR
	sta PGZERO_VECTOR_B+1
	
	lda sp_aux_frame
	sta (PGZERO_VECTOR_B),y
	
	lda #<BUFFER1SPRITESELECTOR
	sta PGZERO_VECTOR_B
	lda #>BUFFER1SPRITESELECTOR
	sta PGZERO_VECTOR_B+1
	
	lda sp_aux_frame
	sta (PGZERO_VECTOR_B),y
	
	; Set the color
	lda #<VIC_SPRCOLOR
	sta PGZERO_VECTOR_B
	lda #>VIC_SPRCOLOR
	sta PGZERO_VECTOR_B+1
		
	ldy #PLAYER_SPR_COLOR
	lda (PGZERO_VECTOR_A),y
	
	ldy sp_aux_idx
	sta (PGZERO_VECTOR_B),y

	rts
	
;===========================================================

readjoystick1

        lda #1
        sta inputx
        sta inputy
        sta inputfire

        ; Joystick check
        lda JOYSTICK1
        lsr
        bcs rj1_noup
        ldx #0
        stx inputy
rj1_noup        
        lsr
        bcs rj1_nodown
        ldx #2
        stx inputy    
rj1_nodown
        lsr
        bcs rj1_noleft
        ldx #0
        stx inputx
rj1_noleft        
        lsr
        bcs rj1_noright
        ldx #2
        stx inputx    
rj1_noright       
        lsr
        bcc rj1_nofire
        ldx #0
        stx inputfire
rj1_nofire
        rts
				
;===========================================================

readjoystick2

        lda #1
        sta inputx
        sta inputy
        sta inputfire

        ; Joystick check
        lda JOYSTICK2
        lsr
        bcs rj2_noup
        ldx #0
        stx inputy
rj2_noup        
        lsr
        bcs rj2_nodown
        ldx #2
        stx inputy    
rj2_nodown
        lsr
        bcs rj2_noleft
        ldx #0
        stx inputx
rj2_noleft        
        lsr
        bcs rj2_noright
        ldx #2
        stx inputx    
rj2_noright       
        lsr
        bcc rj2_nofire
        ldx #0
        stx inputfire
rj2_nofire
        rts